home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Games / SprocketInvaders / Source / MemoryHandler.c < prev    next >
Encoding:
Text File  |  2000-09-28  |  7.4 KB  |  347 lines  |  [TEXT/CWIE]

  1. //•    ------------------------------------------------------------------------------------------    •
  2. //•
  3. //•    Copyright © 1996 Apple Computer, Inc., All Rights Reserved
  4. //•
  5. //•
  6. //•        You may incorporate this sample code into your applications without
  7. //•        restriction, though the sample code has been provided "AS IS" and the
  8. //•        responsibility for its operation is 100% yours.  However, what you are
  9. //•        not permitted to do is to redistribute the source as "DSC Sample Code"
  10. //•        after having made changes. If you're going to re-distribute the source,
  11. //•        we require that you make it clear in the source that the code was
  12. //•        descended from Apple Sample Code, but that you've made changes.
  13. //•
  14. //•        Authors:
  15. //•            Chris De Salvo
  16. //•
  17. //•    ------------------------------------------------------------------------------------------    •
  18.  
  19. /*
  20.     These memory routines are kinda handy and solve a lot of problems on the Mac when dealing
  21.     with memory.  For instance, people often call DisposeHandle() when they mean to call
  22.     ReleaseResource() and it screws up their resource chain.  DisposeHandleZ() checks to see
  23.     if the handle is locked or not, and whether it's a resource or not and takes the appropriate
  24.     action.
  25.     
  26.     All functions ending in 'Z' take the ADDRESS of the Ptr/Handle and set it to nil when it
  27.     disposes of the memory.  This is handy because you can then do things like this:
  28.     
  29.         foo = NewPtr();
  30.         DisposePtrZ(&foo);
  31.             ...
  32.             ...
  33.             
  34.         if (foo)
  35.             ...
  36.     
  37.     Probably the most useful of all this stuff are the tagged Ptr and tagged Handle functions.
  38.     Basically what they do is add 12 bytes to the beginning of every block of memory that you
  39.     allocate.  The first four bytes are the value kBlockTag.  The second is an OSType that
  40.     you provide.  The 3rd group of four bytes is a refcon that you provide.  This is really
  41.     usefull when working with ZoneRanger or other memory watching tool because when you view
  42.     a block of memory you can see your type and refcon and get a clue as to what the memory
  43.     is.  It's really great when you have a memory leak and can't tell what's not getting
  44.     deallocated.  Another use is for tracking resources.  Pass in the resource type as the
  45.     OSType field and the resource number in the refcon.  Then in ZoneRanger you can see
  46.     exactly which resource and number a handle is.
  47.     
  48.     Another use is for reference counting list of similar objects.  If you allocate 200 foos
  49.     then set the OSType to 'foo ' and make the refcon the index of which foo it is.  This is
  50.     helpful for finding off-by-one loop errors when deallocating lists and arrays.
  51.     
  52.     One other thing that has come in really handy is to set the OSType to some identifier saying
  53.     which source file the block was allocated in and setting the refcon to the line number in
  54.     that source file.  That way in ZoneRanger you can tell exactly where that mystery block
  55.     came from.
  56. */
  57.  
  58. //•    ------------------------------    Includes
  59.  
  60. #include <Resources.h>
  61.  
  62. #include <string.h>
  63.  
  64. #include "MemoryHandler.h"
  65.  
  66. //•    ------------------------------    Private Definitions
  67.  
  68. #define kBlockTag                    "TBLK"
  69.  
  70. //•    ------------------------------    Private Types
  71. //•    ------------------------------    Private Variables
  72. //•    ------------------------------    Private Functions
  73. //•    ------------------------------    Public Variables
  74.  
  75. //•    --------------------    IsResourceHandle
  76.  
  77. Boolean
  78. IsResourceHandle(Handle theHandle)
  79. {
  80. SInt8    memState;
  81.  
  82.     memState = HGetState(theHandle);
  83.     
  84.     //•    Check the resource bit in the handle info
  85.     if (memState & 0x20)
  86.         return (true);
  87.         
  88.     return (false);
  89. }
  90. //•    --------------------    IsLockedHandle
  91.  
  92. Boolean
  93. IsLockedHandle(Handle theHandle)
  94. {
  95. SInt8    memState;
  96.  
  97.     //•    Check the lock bit in the handle info
  98.     memState = HGetState(theHandle);
  99.     
  100.     if (memState & 0x80)
  101.         return (true);
  102.         
  103.     return (false);
  104. }
  105.  
  106. //•    --------------------    DisposeControlZ
  107.  
  108. void
  109. DisposeControlZ(ControlHandle *theControl)
  110. {
  111.     if (! (**theControl))
  112.         return;
  113.  
  114.     if (IsLockedHandle((Handle) *theControl))
  115.         HUnlock((Handle) *theControl);
  116.  
  117.     DisposeControl(*theControl);
  118.     *theControl = nil;
  119. }
  120.  
  121. //•    --------------------    DisposeWindowZ
  122.  
  123. void
  124. DisposeWindowZ(WindowRef *theWindow)
  125. {
  126.     if (! *theWindow)
  127.         return;
  128.  
  129.     DisposeWindow(*theWindow);
  130.     *theWindow = nil;
  131. }
  132.  
  133. //•    --------------------    DisposeDialogZ
  134.  
  135. void
  136. DisposeDialogZ(DialogPtr *theWindow)
  137. {
  138.     if (! *theWindow)
  139.         return;
  140.  
  141.     DisposeDialog(*theWindow);
  142.     *theWindow = nil;
  143. }
  144.  
  145. //•    --------------------    DisposeGWorldZ
  146.  
  147. void
  148. DisposeGWorldZ(GWorldPtr *theGWorld)
  149. {
  150.     if (! *theGWorld)
  151.         return;
  152.  
  153.     if (IsLockedHandle((Handle) GetGWorldPixMap(*theGWorld)))
  154.         UnlockPixels(GetGWorldPixMap(*theGWorld));
  155.         
  156.     DisposeGWorld(*theGWorld);
  157.     *theGWorld = nil;
  158. }
  159.  
  160. //•    --------------------    DisposePaletteZ
  161.  
  162. void
  163. DisposePaletteZ(PaletteHandle *thePal)
  164. {
  165.     if (! *thePal)
  166.         return;
  167.  
  168.     if (IsResourceHandle((Handle) *thePal))
  169.         ReleaseResource((Handle) *thePal);
  170.     else
  171.         DisposePalette(*thePal);
  172.         
  173.     *thePal = nil;
  174. }
  175.  
  176. //•    --------------------    KillPictureZ
  177.  
  178. void
  179. KillPictureZ(PicHandle *thePicture)
  180. {
  181.     if (! (**thePicture))
  182.         return;
  183.  
  184.     if (IsLockedHandle((Handle) *thePicture))
  185.         HUnlock((Handle) *thePicture);
  186.  
  187.     if (IsResourceHandle((Handle) *thePicture))
  188.         ReleaseResource((Handle) *thePicture);
  189.     else
  190.         KillPicture(*thePicture);
  191.         
  192.     *thePicture = nil;
  193. }
  194.  
  195. //•    --------------------    DisposePtrZ
  196.  
  197. void
  198. DisposePtrZ(Ptr *thePtr)
  199. {
  200.     if (! *thePtr)
  201.         return;
  202.  
  203.     DisposePtr(*thePtr);
  204.     *thePtr = nil;
  205. }
  206.  
  207. //•    --------------------    DisposeHandleZ
  208.  
  209. void
  210. DisposeHandleZ(Handle *theHandle)
  211. {
  212.     if (! (**theHandle))
  213.         return;
  214.  
  215.     if (IsLockedHandle(*theHandle))
  216.         HUnlock(*theHandle);
  217.         
  218.     if (IsResourceHandle(*theHandle))
  219.         ReleaseResource(*theHandle);
  220.     else
  221.         DisposeHandle(*theHandle);
  222.         
  223.     *theHandle = nil;
  224. }
  225.  
  226. //•    --------------------    TEDisposeZ
  227.  
  228. void
  229. TEDisposeZ(TEHandle *theHandle)
  230. {
  231.     if (! (**theHandle))
  232.         return;
  233.  
  234.     if (IsLockedHandle((Handle) *theHandle))
  235.         HUnlock((Handle) *theHandle);
  236.         
  237.     if (IsResourceHandle((Handle) *theHandle))
  238.         ReleaseResource((Handle) *theHandle);
  239.     else
  240.         TEDispose(*theHandle);
  241. }
  242.  
  243. //•    --------------------    LDisposeZ
  244.  
  245. void
  246. LDisposeZ(ListHandle *theHandle)
  247. {
  248.     if (! (**theHandle))
  249.         return;
  250.  
  251.     if (IsLockedHandle((Handle) *theHandle))
  252.         HUnlock((Handle) *theHandle);
  253.         
  254.     if (IsResourceHandle((Handle) *theHandle))
  255.         ReleaseResource((Handle) *theHandle);
  256.     else
  257.         LDispose(*theHandle);
  258. }
  259.  
  260. //•    --------------------    PurgeAndCompactMem
  261.  
  262. void
  263. PurgeAndCompactMem()
  264. {
  265. Size    growSize;
  266.  
  267.     MaxMem(&growSize);
  268. }
  269.  
  270. //•    --------------------    NewTaggedPtr
  271.  
  272. Ptr
  273. NewTaggedPtr(Size size, OSType tag, UInt32 refCon)
  274. {
  275. Ptr    thePtr;
  276.  
  277.     size += 12;
  278.  
  279.     thePtr = NewPtr(size);
  280.     if (! thePtr)
  281.         return (nil);
  282.  
  283.     BlockMoveData(kBlockTag, thePtr, 4);
  284.     BlockMoveData(&tag, thePtr + 4, 4);
  285.     BlockMoveData(&refCon, thePtr + 8, 4);
  286.     
  287.     return (thePtr + 12);
  288. }
  289.  
  290. //•    --------------------    NewTaggedPtrClear
  291.  
  292. Ptr
  293. NewTaggedPtrClear(Size size, OSType tag, UInt32 refCon)
  294. {
  295. Ptr    thePtr;
  296.  
  297.     size += 12;
  298.  
  299.     thePtr = NewPtrClear(size);
  300.     if (! thePtr)
  301.         return (nil);
  302.  
  303.     BlockMoveData(kBlockTag, thePtr, 4);
  304.     BlockMoveData(&tag, thePtr + 4, 4);
  305.     BlockMoveData(&refCon, thePtr + 8, 4);
  306.     
  307.     return (thePtr + 12);
  308. }
  309.  
  310. //•    --------------------    DisposeTaggedPtr
  311.  
  312. void
  313. DisposeTaggedPtr(Ptr thePtr)
  314. {
  315. Ptr    ptr2;
  316.  
  317.     if (! thePtr)
  318.         return;
  319.  
  320.     ptr2 = thePtr - 12;
  321.     
  322.     //•    Confirm that this is one of our tagged blocks first
  323.     if (strncmp(kBlockTag, ptr2, 4) == 0)
  324.         DisposePtr(ptr2);
  325.     else
  326.         DisposePtr(thePtr);
  327. }
  328.  
  329. //•    --------------------    DisposeTaggedPtrZ
  330.  
  331. void
  332. DisposeTaggedPtrZ(Ptr *thePtr)
  333. {
  334. Ptr    ptr2;
  335.  
  336.     if (! *thePtr)
  337.         return;
  338.  
  339.     ptr2 = (*thePtr) - 12;
  340.     if (strncmp(kBlockTag, ptr2, 4) == 0)
  341.         DisposePtr(ptr2);
  342.     else
  343.         DisposePtr(*thePtr);
  344.         
  345.     *thePtr = nil;
  346. }
  347.